<?php


namespace Melon\Foundation;


class Response
{
    /**
     * @var resource
     */
    protected $conn;

    /**
     * Header头部
     * @var array
     */
    protected array $header = [
        "Server" => "Melon",
        "Transfer-Encoding" => "chunk",
        "X-Powered-By" => "PHP/" . PHP_VERSION,
        "Connection" => "keep-alive",
        "Content-Type" => 'text/html',
    ];

    /**
     * 内容
     * @var string
     */
    protected string $content = '';

    protected int $statusCode = 200;

    /**
     * Status codes translation table.
     *
     * The list of codes is complete according to the
     * {@link https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml Hypertext Transfer Protocol (HTTP) Status Code Registry}
     * (last updated 2016-03-01).
     *
     * Unless otherwise noted, the status code is defined in RFC2616.
     *
     * @var array
     */
    public static array $statusTexts = [
        100 => 'Continue',
        101 => 'Switching Protocols',
        102 => 'Processing',            // RFC2518
        103 => 'Early Hints',
        200 => 'OK',
        201 => 'Created',
        202 => 'Accepted',
        203 => 'Non-Authoritative Information',
        204 => 'No Content',
        205 => 'Reset Content',
        206 => 'Partial Content',
        207 => 'Multi-Status',          // RFC4918
        208 => 'Already Reported',      // RFC5842
        226 => 'IM Used',               // RFC3229
        300 => 'Multiple Choices',
        301 => 'Moved Permanently',
        302 => 'Found',
        303 => 'See Other',
        304 => 'Not Modified',
        305 => 'Use Proxy',
        307 => 'Temporary Redirect',
        308 => 'Permanent Redirect',    // RFC7238
        400 => 'Bad Request',
        401 => 'Unauthorized',
        402 => 'Payment Required',
        403 => 'Forbidden',
        404 => 'Not Found',
        405 => 'Method Not Allowed',
        406 => 'Not Acceptable',
        407 => 'Proxy Authentication Required',
        408 => 'Request Timeout',
        409 => 'Conflict',
        410 => 'Gone',
        411 => 'Length Required',
        412 => 'Precondition Failed',
        413 => 'Payload Too Large',
        414 => 'URI Too Long',
        415 => 'Unsupported Media Type',
        416 => 'Range Not Satisfiable',
        417 => 'Expectation Failed',
        418 => 'I\'m a teapot',                                               // RFC2324
        421 => 'Misdirected Request',                                         // RFC7540
        422 => 'Unprocessable Entity',                                        // RFC4918
        423 => 'Locked',                                                      // RFC4918
        424 => 'Failed Dependency',                                           // RFC4918
        425 => 'Too Early',                                                   // RFC-ietf-httpbis-replay-04
        426 => 'Upgrade Required',                                            // RFC2817
        428 => 'Precondition Required',                                       // RFC6585
        429 => 'Too Many Requests',                                           // RFC6585
        431 => 'Request Header Fields Too Large',                             // RFC6585
        451 => 'Unavailable For Legal Reasons',                               // RFC7725
        500 => 'Internal Server Error',
        501 => 'Not Implemented',
        502 => 'Bad Gateway',
        503 => 'Service Unavailable',
        504 => 'Gateway Timeout',
        505 => 'HTTP Version Not Supported',
        506 => 'Variant Also Negotiates',                                     // RFC2295
        507 => 'Insufficient Storage',                                        // RFC4918
        508 => 'Loop Detected',                                               // RFC5842
        510 => 'Not Extended',                                                // RFC2774
        511 => 'Network Authentication Required',                             // RFC6585
    ];

    public function __construct(?string $content, int $status = 200, array $header = []){
        $this->headers = array_merge_recursive($this->header, $header);

        $this->setContent($content);
        $this->setStatusCode($status);
    }

    /**
     * 输出流
     * @param $conn
     * @return void
     */
    public function send($conn) {
        $this->conn = $conn;
        $this->sendHeaders();
        $this->sendContent();
    }

    protected function sendHeaders() {
        fwrite($this->conn, "HTTP/1.1 " . $this->statusCode . " " . self::$statusTexts[$this->statusCode] . "\r\n");

        foreach ($this->header as $key => $item) {
            fwrite($this->conn, "$key: $item" . "\r\n");
        }

        fwrite($this->conn, "\r\n");
    }

    /**
     * 发送内容
     * @return void
     */
    public function sendContent()
    {
        fwrite($this->conn, $this->content . "\r\n");
    }

    /**
     * 设置内容
     * @param string $content
     * @return $this
     */
    public function setContent(string $content = "") :self {
        $this->content = $content;
        return $this;
    }

    public function setStatusCode(int $code): object
    {
        $this->statusCode = $code;

        return $this;
    }

    public function __destruct()
    {
        fclose($this->conn);
    }
}
